﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FimetContoDeposito.BLL.Objects;
using FimetContoDeposito.DAL;
using GrayParrot.Core;

namespace FimetContoDeposito.BLL.Facades
{
    public class AnagraficaArticoliFacade : FacadeBase<AnagraficaArticoliFacade>
    {
        const string DefaultFoto = "http://placehold.it/350x150/7ba9d0/fff?text=immagine+articolo+%3A%29";

        FCDContext m_ctx = null;

        public Repository<FCD_AnagraficaArticoli, Guid> Repo { get; internal set; }


        public AnagraficaArticoliFacade()
        {
        }

        public override void Initialize()
        {
            m_ctx = new FCDContext();
            m_ctx.Configuration.LazyLoadingEnabled = false;
            m_ctx.Configuration.ProxyCreationEnabled = false;

            Repo = this.GetRepository<FCD_AnagraficaArticoli, Guid>(m_ctx);
        }

        public override void Dispose()
        {
            if (m_ctx != null)
            {
                m_ctx.Dispose();

                Repo.Dispose();
            }
        }

        public ReturnValue<bool> Add(FCD_AnagraficaArticoli item)
        {
            ReturnValue<bool> retValue = new ReturnValue<bool>();

            try
            {
                if (item.Id == Guid.Empty)
                {
                    item.Id = Guid.NewGuid();
                }

                this.Repo.Add(item);
                this.Repo.Save();

                retValue.HasValue = true;
                retValue.Value = true;
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<bool> Edit(FCD_AnagraficaArticoli item)
        {
            ReturnValue<bool> retValue = new ReturnValue<bool>(false);

            try
            {
                this.Repo.Edit(item);
                this.Repo.Save();

                retValue.HasValue = true;
                retValue.Value = true;
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<bool> Delete(FCD_AnagraficaArticoli item)
        {
            ReturnValue<bool> retValue = new ReturnValue<bool>();

            try
            {
                this.Repo.Delete(item);
                this.Repo.Save();

                retValue.HasValue = true;
                retValue.Value = true;
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<bool> Delete(Guid idArticolo)
        {
            ReturnValue<bool> retValue = new ReturnValue<bool>();

            try
            {
                ReturnValue<FCD_AnagraficaArticoli> obj = this.Get(idArticolo);
                if (obj.HasValue)
                {
                    retValue = this.Delete(obj.Value);
                }
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<FCD_AnagraficaArticoli> Get(Guid id)
        {
            ReturnValue<FCD_AnagraficaArticoli> retValue = new ReturnValue<FCD_AnagraficaArticoli>();

            try
            {
                retValue.Value = this.Repo.Get(id);
                retValue.HasValue = true;
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<FCD_AnagraficaArticoli> Get(Guid id, string includes)
        {
            ReturnValue<FCD_AnagraficaArticoli> retValue = new ReturnValue<FCD_AnagraficaArticoli>();

            try
            {
                retValue.Value = this.Repo.Get(x => x.Id == id, null, includes).FirstOrDefault();
                retValue.HasValue = true;
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<IQueryable<FCD_AnagraficaArticoli>> GetAll()
        {
            ReturnValue<IQueryable<FCD_AnagraficaArticoli>> retValue = new ReturnValue<IQueryable<FCD_AnagraficaArticoli>>();
            retValue.HasValue = false;
            retValue.Value = null;

            try
            {
                retValue.Value = this.Repo.GetAll();
                retValue.HasValue = true;
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<IQueryable<FCD_AnagraficaArticoli>> GetAllByCustomer(Guid idCustomer)
        {
            ReturnValue<IQueryable<FCD_AnagraficaArticoli>> retValue = new ReturnValue<IQueryable<FCD_AnagraficaArticoli>>();
            retValue.HasValue = false;
            retValue.Value = null;

            try
            {
                var objs = from x in m_ctx.FCD_AnagraficaArticolis
                           where x.IdCliente == idCustomer
                           select x;

                if (objs.Any())
                {
                    retValue.Value = objs;
                    retValue.HasValue = true;
                }
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<IQueryable<ArticoloBag>> GetAllArticoliBag()
        {
            ReturnValue<IQueryable<ArticoloBag>> retValue = new ReturnValue<IQueryable<ArticoloBag>>();
            retValue.HasValue = false;
            retValue.Value = null;

            try
            {
                var objs = from x in m_ctx.FCD_VwAnagraficaArticolis
                           select new ArticoloBag() { 
                             Codice = x.Codice,
                             Descrizione = x.Descrizione,
                             Id = x.Id,
                             IsAbilitato = x.IsAbilitato,
                             PesoTeorico = x.PesoTeorico.Value,
                             PrezzoUnitario = x.PrezzoUnitario.Value,
                             ScontoFornitore = x.ScontoFornitore.Value,
                             ScortaMinima = x.ScortaMinima.Value,
                             DescrTipologia = (x.DescrTipologia == null ? string.Empty : x.DescrTipologia),
                             Tipologia  = x.Tipologia,
                             UnitaDiMisura = x.UnitaDiMisura,
                             DescrUnitaDiMisura = x.DescrUnitaDiMisura,
                             IdCliente = x.IdCliente,
                             DescrCliente = x.DescrCliente,
                             FotoArticolo = x.Foto,
                             SerieFamiglia = (x.SerieFamiglia == null ? string.Empty : x.SerieFamiglia),
                             QtaPacco = (x.QtaPacco == null ? 1 : x.QtaPacco),
                             Dimensioni = (x.Dimensioni == null ? string.Empty : x.Dimensioni),
                             UMFatt = x.UnitaDiMisuraFatt,
                             DescrUMFatt = x.DescrUnitaDiMisuraFatt,
                             Note = (x.Note == null ? string.Empty : x.Note),
                             CodiceFornitore = (x.CodiceFornitore.HasValue ? x.CodiceFornitore : null),
                             DescrCodiceFornitore = x.DescrCodiceFornitore
                           };

                if (objs.Any())
                {
                    retValue.Value = objs;
                    retValue.HasValue = true;
                }
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public List<ArticoloBag> GetAllArticoliBagReport(Guid idMagazzino)
        {
            List<ArticoloBag> retValue = new List<ArticoloBag>();

            ReturnValue<IQueryable<ArticoloBag>> res = GetAllArticoliBag(idMagazzino);

            if (res.HasValue && res.Value != null)
            {
                retValue = res.Value.ToList();
            }

            return retValue;
        }

        public ReturnValue<IQueryable<ArticoloBag>> GetAllArticoliBag(Guid idMagazzino)
        {
            ReturnValue<IQueryable<ArticoloBag>> retValue = new ReturnValue<IQueryable<ArticoloBag>>();
            retValue.HasValue = false;
            retValue.Value = null;

            try
            {
                var objs = from x in m_ctx.FCD_VwAnagraficaArticolis
                           where x.IdCliente == idMagazzino
                           select new ArticoloBag()
                           {
                               Codice = x.Codice,
                               Descrizione = x.Descrizione,
                               Id = x.Id,
                               IsAbilitato = x.IsAbilitato,
                               PesoTeorico = x.PesoTeorico.Value,
                               PrezzoUnitario = x.PrezzoUnitario.Value,
                               ScontoFornitore = x.ScontoFornitore.Value,
                               ScortaMinima = x.ScortaMinima.Value,
                               DescrTipologia = (x.DescrTipologia == null ? string.Empty : x.DescrTipologia),
                               Tipologia = x.Tipologia,
                               UnitaDiMisura = x.UnitaDiMisura,
                               DescrUnitaDiMisura = x.DescrUnitaDiMisura,
                               IdCliente = x.IdCliente,
                               DescrCliente = x.DescrCliente,
                               FotoArticolo = x.Foto,
                               SerieFamiglia = (x.SerieFamiglia == null ? string.Empty : x.SerieFamiglia),
                               QtaPacco = (x.QtaPacco == null ? 1 : x.QtaPacco),
                               Dimensioni = (x.Dimensioni == null ? string.Empty : x.Dimensioni),
                               UMFatt = x.UnitaDiMisuraFatt,
                               DescrUMFatt = x.DescrUnitaDiMisuraFatt,
                               Note = (x.Note == null ? string.Empty : x.Note),
                               CodiceFornitore = (x.CodiceFornitore.HasValue ? x.CodiceFornitore : null),
                               DescrCodiceFornitore = x.DescrCodiceFornitore,
                               IsXxxx = x.IsXxxx.Value
                           };

                if (objs.Any())
                {
                    retValue.Value = objs;
                    retValue.HasValue = true;
                }
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<ArticoloBag> GetArticoloBag(Guid id)
        {
            ReturnValue<ArticoloBag> retValue = new ReturnValue<ArticoloBag>();
            retValue.HasValue = false;
            retValue.Value = null;

            try
            {
                var objs = from x in m_ctx.FCD_VwAnagraficaArticolis
                           where x.Id == id
                           select new ArticoloBag()
                           {
                               Codice = x.Codice,
                               Descrizione = x.Descrizione,
                               Id = x.Id,
                               IsAbilitato = x.IsAbilitato,
                               PesoTeorico = x.PesoTeorico.Value,
                               PrezzoUnitario = x.PrezzoUnitario.Value,
                               ScontoFornitore = x.ScontoFornitore.Value,
                               ScortaMinima = x.ScortaMinima.Value,
                               DescrTipologia = (x.DescrTipologia == null ? string.Empty : x.DescrTipologia),
                               Tipologia = x.Tipologia,
                               UnitaDiMisura = x.UnitaDiMisura,
                               DescrUnitaDiMisura = x.DescrUnitaDiMisura,
                               IdCliente = x.IdCliente,
                               DescrCliente = x.DescrCliente,
                               FotoArticolo = (x.Foto == string.Empty ? DefaultFoto : x.Foto),
                               SerieFamiglia = (x.SerieFamiglia == null ? string.Empty : x.SerieFamiglia),
                               QtaPacco = (x.QtaPacco == null ? 1 : x.QtaPacco),
                               Dimensioni = (x.Dimensioni == null ? string.Empty : x.Dimensioni),
                               UMFatt = x.UnitaDiMisuraFatt,
                               DescrUMFatt = (x.DescrUnitaDiMisuraFatt == null ? string.Empty : x.DescrUnitaDiMisuraFatt),
                               Note = (x.Note == null ? string.Empty : x.Note),
                               CodiceFornitore = (x.CodiceFornitore.HasValue ? x.CodiceFornitore : null),
                               DescrCodiceFornitore = (x.DescrCodiceFornitore == null ? string.Empty : x.DescrCodiceFornitore),
                               Fornitore = x.IdFornitore
                           };

                if (objs.Any())
                {
                    retValue.Value = objs.FirstOrDefault();
                    retValue.HasValue = true;
                }
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<ArticoloBag> GetArticoloBag(Guid idArticolo, Guid IdFornitore)
        {
            ReturnValue<ArticoloBag> retValue = new ReturnValue<ArticoloBag>();
            retValue.HasValue = false;
            retValue.Value = null;

            try
            {
                var objs = from x in m_ctx.FCD_VwAnagraficaArticolis
                           where x.Id == idArticolo && x.IdFornitore == IdFornitore
                           select new ArticoloBag()
                           {
                               Codice = x.Codice,
                               Descrizione = x.Descrizione,
                               Id = x.Id,
                               IsAbilitato = x.IsAbilitato,
                               PesoTeorico = x.PesoTeorico.Value,
                               PrezzoUnitario = x.PrezzoUnitario.Value,
                               ScontoFornitore = x.ScontoFornitore.Value,
                               ScortaMinima = x.ScortaMinima.Value,
                               DescrTipologia = (x.DescrTipologia == null ? string.Empty : x.DescrTipologia),
                               Tipologia = x.Tipologia,
                               UnitaDiMisura = x.UnitaDiMisura,
                               DescrUnitaDiMisura = x.DescrUnitaDiMisura,
                               IdCliente = x.IdCliente,
                               DescrCliente = x.DescrCliente,
                               FotoArticolo = (x.Foto == string.Empty ? DefaultFoto : x.Foto),
                               SerieFamiglia = (x.SerieFamiglia == null ? string.Empty : x.SerieFamiglia),
                               QtaPacco = (x.QtaPacco == null ? 1 : x.QtaPacco),
                               Dimensioni = (x.Dimensioni == null ? string.Empty : x.Dimensioni),
                               UMFatt = x.UnitaDiMisuraFatt,
                               DescrUMFatt = (x.DescrUnitaDiMisuraFatt == null ? string.Empty : x.DescrUnitaDiMisuraFatt),
                               Note = (x.Note == null ? string.Empty : x.Note),
                               CodiceFornitore = (x.CodiceFornitore.HasValue ? x.CodiceFornitore : null),
                               DescrCodiceFornitore = (x.DescrCodiceFornitore == null ? string.Empty : x.DescrCodiceFornitore),
                               Fornitore = x.IdFornitore
                           };

                if (objs.Any())
                {
                    retValue.Value = objs.FirstOrDefault();
                    retValue.HasValue = true;
                }
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<IEnumerable<NameValue<string, Guid>>> GetAllNameValue()
        {
            ReturnValue<IEnumerable<NameValue<string, Guid>>> retValue = new ReturnValue<IEnumerable<NameValue<string, Guid>>>();
            retValue.Value = null;
            retValue.HasValue = false;

            var objs = from x in m_ctx.FCD_AnagraficaArticolis
                       select new NameValue<string, Guid>()
                       {
                           value = x.Id,
                           name = x.Descrizione
                       };

            if (objs.Any())
            {
                retValue.HasValue = true;
                retValue.Value = objs;
            }
            else
            {
                NameValue<string, Guid> dummy = new NameValue<string, Guid>();
                dummy.value = Guid.Empty;
                dummy.name = "Nessun Elemento disponibile";

                List<NameValue<string, Guid>> m_l = new List<NameValue<string, Guid>>();
                m_l.Add(dummy);

                retValue.HasValue = true;
                retValue.Value = m_l.AsEnumerable();
            }

            return retValue;
        }

        public ReturnValue<string> GetFoto(Guid id)
        {
            ReturnValue<string> retValue = new ReturnValue<string>();
            retValue.HasValue = false;
            retValue.Value = string.Empty;

            try
            {
                var objs = from x in m_ctx.FCD_AnagraficaArticolis
                           where x.Id == id
                           select x.Foto;

                if (objs.Any())
                {
                    retValue.Value = objs.FirstOrDefault();
                    retValue.HasValue = true;
                }
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<IQueryable<NameValue<string, Guid>>> GetAllCodice(Guid idCustomer)
        {
            ReturnValue<IQueryable<NameValue<string, Guid>>> retValue = new ReturnValue<IQueryable<NameValue<string, Guid>>>();
            retValue.HasValue = false;
            retValue.Value = null;

            try
            {
                var objs = from x in m_ctx.FCD_AnagraficaArticolis
                           where x.IdCliente == idCustomer
                           orderby x.Codice ascending
                           select new NameValue<string, Guid>()
                           {
                               name = x.Codice,
                               value = x.Id
                           };

                if (objs.Any())
                {
                    retValue.Value = objs;
                    retValue.HasValue = true;
                }
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public ReturnValue<decimal> GetQtaPacco(Guid id)
        {
            ReturnValue<decimal> retValue = new ReturnValue<decimal>();
            retValue.HasValue = false;
            retValue.Value = 0;

            try
            {
                var objs = from x in m_ctx.FCD_AnagraficaArticolis
                           where x.Id == id
                           select x.QtaPacco;

                if (objs.Any())
                {
                    decimal? m = objs.FirstOrDefault();

                    retValue.Value = (m.HasValue ? m.Value : 0);
                    retValue.HasValue = true;
                }
            }
            catch (Exception ex)
            {
                retValue.HasError = true;
                retValue.Error = ex;
            }

            return retValue;
        }

        public int GetCodiceXXXX()
        {
            int retValue = -1;

            int m_max = m_ctx.FCD_AnagraficaArticolis.Max(x => x.CodiceXxxx);

            if (m_max > -1)
            {
                retValue = m_max + 1;
            }

            return retValue;
        }
    }
}
